# -*- coding: utf-8 -*-
import random

from mod.common.minecraftEnum import ActorDamageCause
import math
from ..common.base import CombineEntityBase
from ...mdk.common.system.base import *
from ...mdk.server.entity import *
from ...mdk.common.utils.misc import Misc


class MantisChomperEntity(CombineEntityBase):
    """巨斧啃灵兽"""

    def __init__(self, entityId):
        super(MantisChomperEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(MantisChomperEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "mantis_chomper_attack"
        })

        def active():
            if self._owner_player:
                yield 19
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(19):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                self.SetInstantDamage(entityId, self.attack)
                self.SetKnockEntityAtPos(entityId, 3, 2)
            yield 11
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(MantisChomperEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "mantis_chomper_sk1"
            })
            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            ban_set = {self.id, }
            self.SetJumpByKnock(0.8)
            yield 6
            self.SetForwardByKnock(4.0)
            yield 15
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 4):
                if entityId not in ban_set:
                    ban_set.add(entityId)
                    self.SetInstantDamage(entityId, self.sk1_damage)
                    # self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
                self.SetKnockEntityAtPos(entityId, 2, 3)
            yield 18
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(MantisChomperEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "mantis_chomper_sk2"
            })

            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            for i in range(10):
                self.SetForwardByKnock(1.0)
                yield 1

            ban_set = {self.id, self._owner_player}
            pos = self.GetPosForward(2)
            for entityId in self.GetMobAtPos(pos, 3):
                if entityId not in ban_set:
                    self.SetInstantDamage(entityId, self.sk2_damage)
                    self.SetKnockEntityAtPos(entityId, 5, 4)
            yield 32
            self.TriggerResetSkill()

        self.StartCoroutine(active)


class BearCrocodileEntity(CombineEntityBase):
    """威烈蛟尾兽"""

    def __init__(self, entityId):
        super(BearCrocodileEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(BearCrocodileEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "bear_crocodile_attack"
        })

        def active():
            if self._owner_player:
                yield 10
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(10):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                self.SetInstantDamage(entityId, self.attack)
                self.SetKnockEntityAtPos(entityId, 3, 2)
            yield 11
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(BearCrocodileEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "bear_crocodile_sk1_1"
            })
            if self._owner_player:
                yield 6
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(6):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            ban_set = {self.id, }
            self.SetJumpByKnock(0.6)
            yield 5
            self.SetForwardByKnock(2.0)
            yield 8
            pos = self.GetPosForward(0)
            particle = self.AddParticleEntity(GameEntity.detector, pos=self.GetPosForward(5, dy=1.7))
            particle.SetModel("base_entity")
            particle.SetFixBind("models/bind/v15_bind.json", "bear_crocodile_sk1").Destroy(1.0).Play()
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "bear_crocodile_sk1_2"
            })
            for entityId in self.GetMobAtPos(pos, 4):
                if entityId not in ban_set:
                    ban_set.add(entityId)
                    self.SetInstantDamage(entityId, self.sk1_damage)
                    # self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
                self.SetKnockEntityAtPos(entityId, 2, 3)
            yield 10
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(BearCrocodileEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "bear_crocodile_sk2"
            })

            if self._owner_player:
                yield 6
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(6):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            particle = self.AddParticleEntity(GameEntity.detector, pos=self.GetPosForward(5, dy=1.7))
            particle.SetModel("base_entity")
            particle.SetFixBind("models/bind/v15_bind.json", "bear_crocodile_sk2").Destroy(1.0).Play()
            particle.SetTrackEntity(self.id, forward=3)
            if not self.IsAlive():
                return
            ban_set = {self.id, self._owner_player}

            self.AddTag("sk2")
            for i in range(15):
                pos = self.GetPosForward(0)
                self.SetForwardByKnock(2.0)
                self.command_comp.SetCommand(
                    "/execute @e[type=beast:bear_crocodile,tag=sk2] ~~~ fill ~-3~~-3 ~3~5~3 air", self._owner_player)
                for entityId in self.GetMobAtPos(pos, 3):
                    if entityId not in ban_set:
                        self.SetInstantDamage(entityId, 20)
                        self.SetKnockEntityAtPos(entityId, 5, 4)
                        ban_set.add(entityId)
                yield 1
            self.RemoveTag("sk2")

            yield 15
            self.TriggerResetSkill()

        self.StartCoroutine(active)


class BearBullileEntity(CombineEntityBase):
    """威烈蛟尾兽"""

    def __init__(self, entityId):
        super(BearBullileEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(BearBullileEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "bear_bull_attack"
        })

        def active():
            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            for i in range(2):
                pos = self.GetPosForward(0)
                for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                    self.SetInstantDamage(entityId, self.attack)
                    self.SetKnockEntityAtPos(entityId, 2, 1)
                yield 10
            yield 5
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(BearBullileEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def GunHit(projectile):
            hitType = projectile.hitType
            hitPos = projectile.GetHitPos()
            for entityId in self.GetMobAtPos(hitPos, 6, banList=[self.id, projectile.id, self._owner_player],
                                             filters=GameFilter.Mob):
                self.SetInstantDamage(entityId, 20)
                self.SetKnockEntityAtPos(entityId, 7, 5, height=1)
            if hitType == "ENTITY":
                def func():
                    comp = serverApi.GetEngineCompFactory().CreateBlockInfo(serverApi.GetLevelId())
                    pos = hitPos
                    IntPos = tuple(map(int, pos))
                    comp.SetBlockNew(IntPos, {"name": "minecraft:water"}, 0, self.dim, True)
                    yield 120
                    comp.SetBlockNew(IntPos, {"name": "minecraft:air"}, 0, self.dim, True)

                self.StartCoroutine(func())

        def active():
            """枪普攻"""
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "bear_bull_sk1"
            })
            if self._owner_player:
                dir = self.drt
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                dir = self.GetFacingVec(RawEntity.GetPos(targetId))
                for i in xrange(12):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            yield 1
            pos = self.GetPosForward(1.5, dy=5.2, dx=0)

            projectile = ProjectileEntity.CreateFromEntity(GameEntity.projectile, self.id,
                                                           position=pos,
                                                           direction=dir,
                                                           power=2.0,
                                                           gravity=0.1)
            projectile.ConfigHitRecall(GunHit)
            projectile = projectile.asParticleEntity()
            projectile.SetModel("base_entity").Destroy(5.0).SetFixBind("models/bind/v15_bind.json",
                                                                       "bear_bull_sk1").Play()
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(BearBullileEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "bear_bull_sk2"
            })

            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1

            if not self.IsAlive():
                return
            ban_set = {self.id, self._owner_player}
            pos = self.GetPosForward(0)
            self.SetForwardByKnock(2.0)
            for entityId in self.GetMobAtPos(pos, 3):
                if entityId not in ban_set:
                    self.SetInstantDamage(entityId, self.sk1_damage)
            yield 10
            for i in range(8):
                pos = self.GetPosForward(0)
                self.SetForwardByKnock(2.0)
                for entityId in self.GetMobAtPos(pos, 3):
                    if entityId not in ban_set:
                        self.SetInstantDamage(entityId, self.sk1_damage)
                        self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
                        ban_set.add(entityId)
                yield 1
            yield 15
            self.TriggerResetSkill()

        self.StartCoroutine(active)


class TurtleFrogEntity(CombineEntityBase):
    """锐壳雷鸣兽"""

    def __init__(self, entityId):
        super(TurtleFrogEntity, self).__init__(entityId)
        self.sk1_time = False
        self.sk1_particle = None
        self.sound_repeat = self.game_comp.AddRepeatedTimer(0.2, self.update_sound)

    def OnDealDamage(self, args):
        entityId = args["entityId"]
        if args["damage"] == 1999:
            args["damage"] = 0
            args["knock"] = False
            if self.sk1_time:
                """打断"""
                if entityId in {self.id, self._owner_player}:
                    return
                self.sk1_stop()

    def sk1_stop(self):
        ban_set = {self.id, self._owner_player}
        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "turtle_frog_sk1_2"
        })
        self.sk1_particle.Destroy()
        self.DelEffect(GameEffect.MOVEMENT_SPEED)
        self.TriggerResetSkill()
        self.RemoveTag("sk1")
        pos = self.GetPosForward(0)
        for entityId in self.GetMobAtPos(pos, 4):
            if entityId not in ban_set:
                self.SetInstantDamage(entityId, self.sk1_damage)
                self.SetKnockEntityAtPos(entityId, 3, 2)
                ban_set.add(entityId)
        self.sk1_time = False

    def update_sound(self):
        if self.sk1_time:
            self.command_comp.SetCommand(
                "/execute @e[type=beast:turtle_frog,tag=sk1] ~~~ fill ~-3~~-3 ~3~5~3 air", self._owner_player)

    def ActiveAttack(self):
        super(TurtleFrogEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "turtle_frog_attack"
        })

        def active():
            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            for i in range(2):
                pos = self.GetPosForward(0)
                for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                    self.SetInstantDamage(entityId, self.attack)
                    self.SetKnockEntityAtPos(entityId, 2, 1)
                yield 10
            yield 5
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        """但滚动有一个问题，就是如果不是玩家骑乘控制释放的时候，只是有个滚动状态，但不会动，并不会自己跑向敌人。
            所以如果优化的话我们可以判断是不是骑乘状态。然后如果不是的话，就自己用代码让他面向敌人，然后给突进
        """
        super(TurtleFrogEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "turtle_frog_sk1_1"
            })
            if self._owner_player:
                yield 6
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(6):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            self.AddEffect(GameEffect.MOVEMENT_SPEED, 5, 2)

            self.sk1_time = True
            self.AddTag("sk1")
            self.sk1_particle = self.AddParticleEntity(GameEntity.detector, pos=self.GetPosForward(0, dy=0))
            self.sk1_particle.SetModel("base_entity")
            self.sk1_particle.SetFixBind("models/bind/v15_bind.json", "turtle_frog_sk1").Play()
            self.sk1_particle.SetTrackEntity(self.id, forward=0)
            if not self.GetRiders():
                """如果没有骑乘者，就自己跑向敌人"""
                targetId = self.GetAttackTarget()
                for i in xrange(30):
                    if not self.IsAlive() or not self.sk1_time:
                        return
                    self.SetFacingEntity(targetId)
                    self.SetForwardByKnock(2)
                    yield 5
            else:
                yield 5 * 30
            if not self.sk1_time:
                return
            self.sk1_particle.Destroy()
            self.TriggerResetSkill()
            self.sk1_time = False
            self.RemoveTag("sk1")

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(TurtleFrogEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "turtle_frog_sk2_1"
            })

            if self._owner_player:
                yield 16
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 2

            if not self.IsAlive():
                return
            ban_set = {self.id, self._owner_player}
            pos = self.GetPosForward(4)
            for entityId in self.GetMobAtPos(pos, 5):
                if entityId not in ban_set:
                    self.SetInstantDamage(entityId, self.sk2_damage)
                    # self.SetKnockEntityAtPos(entityId, 5, 4)
                    ban_set.add(entityId)
                    yield 8
                    self.sk2_func(entityId)
                    break
            yield 5
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def sk2_func(self, entityId):
        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "turtle_frog_sk2_2"
        })
        if not entityId or not RawEntity.IsAlive(entityId):
            return
        entity = LivingEntity(entityId)
        endPos = self.GetPosForward(0)
        pos = entity.GetPos()
        distance = Misc.GetDistBetween(pos, endPos)
        actionComp = self.comp_factory.CreateAction(entityId)
        motion = entity.GetFacingVec(endPos)
        # height = max(-0.5, min(1.5, (endPos[1] - pos[1] + 2) * 0.2))
        actionComp.SetMobKnockback(motion[0] * 3, motion[2] * 3, 6, 0, 1.5)

    def OnDestroy(self):
        super(TurtleFrogEntity, self).OnDestroy()
        self.game_comp.CancelTimer(self.sound_repeat)
        self.sk1_particle.Destroy()


class FrogBeeEntity(CombineEntityBase):
    """雷鸣刺皇兽"""

    def __init__(self, entityId):
        super(FrogBeeEntity, self).__init__(entityId)
        self.on_fly = False

    def ActiveAttack(self):
        super(FrogBeeEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "frog_bee_attack"
        })

        def active():
            if self._owner_player:
                yield 13
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(13):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                self.SetInstantDamage(entityId, self.attack)
                self.SetKnockEntityAtPos(entityId, 3, 2)
            yield 11
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        """未完成"""
        super(FrogBeeEntity, self).ActiveSkill1()

        def GunHit(projectile):
            hitPos = projectile.GetHitPos()
            for entityId in self.GetMobAtPos(hitPos, 6, banList=[self.id, projectile.id, self._owner_player],
                                             filters=GameFilter.Mob):
                self.SetInstantDamage(entityId, self.sk1_damage)
                RawEntity.AddEffect(entityId, GameEffect.MOVEMENT_SLOWDOWN, 3, 0)
                if random.randint(1, 10) == 1:
                    RawEntity.CreateRaw(GameEntity.lightning_bolt, pos=hitPos, dim=self.dim)
                # self.SetKnockEntityAtPos(entityId, 7, 5, height=1)

        def active():
            """枪普攻"""
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "frog_bee_sk1"
            })
            if self._owner_player:
                dir = self.drt
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                dir = self.GetFacingVec(RawEntity.GetPos(targetId))
                for i in xrange(15):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            for i in range(14):
                if not self.GetRiders():
                    """如果没有骑乘者，就自己跑向敌人"""
                    targetId = self.GetAttackTarget()
                    if targetId:
                        # 设置面向
                        self.SetFacingEntity(targetId)
                pos = self.GetPosForward(4.3, dy=2.4, dx=0)
                projectile = ProjectileEntity.CreateFromEntity(GameEntity.projectile, self.id,
                                                               position=pos,
                                                               direction=self.drt,
                                                               power=2.0,
                                                               gravity=0.1)
                projectile.ConfigHitRecall(GunHit)
                projectile = projectile.asParticleEntity()
                projectile.SetModel("base_entity").Destroy(5.0).SetFixBind("models/bind/v15_bind.json",
                                                                           "frog_bee_sk1").Play()
                yield 5
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(FrogBeeEntity, self).ActiveSkill2()

        def GunHit(projectile):
            # hitType = projectile.hitType
            hitPos = projectile.GetHitPos()
            particle = self.AddParticleEntity(GameEntity.detector, pos=hitPos)
            particle.SetModel("base_entity")
            particle.SetFixBind("models/bind/v15_bind.json", "frog_bee_sk2_dj").Destroy(2.0).Play()
            for entityId in self.GetMobAtPos(hitPos, 6, banList=[self.id, projectile.id, self._owner_player],
                                             filters=GameFilter.Mob):
                self.SetInstantDamage(entityId, self.sk2_damage)
                # self.SetKnockEntityAtPos(entityId, 7, 5, height=1)

        def active():
            """枪普攻"""
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "frog_bee_sk2"
            })
            if self._owner_player:
                yield 16
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(16):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            yield 1
            pos = self.GetPosForward(1.5, dy=5.2, dx=0)

            projectile = ProjectileEntity.CreateFromEntity(GameEntity.projectile, self.id,
                                                           position=pos,
                                                           direction=self.drt,
                                                           power=2.0,
                                                           gravity=0.1)
            projectile.ConfigHitRecall(GunHit)
            projectile.ConfigDestroyOnHit(False)
            projectile = projectile.asParticleEntity()
            projectile.SetModel("base_entity").Destroy(5.0).SetFixBind("models/bind/v15_bind.json",
                                                                       "frog_bee_sk2").Play()
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def OnScriptTickServer(self):
        super(FrogBeeEntity, self).OnScriptTickServer()
        if not self.FlyLoop() and self.on_fly:
            self.on_fly = False
            self.StopFly()

    def FlyLoop(self):
        playerId = self.GetTameOwner()
        if not playerId or PlayerEntity(playerId).GetOnRideEntity() != self.id:
            return False
        self.on_fly = True
        face = RawEntity.GetDrt(playerId)

        p = math.atan2(face[1], face[0])
        p2 = math.degrees(p)
        p3 = math.atan2(face[1], face[2])
        p4 = math.degrees(p3)

        if p2 > 15 or p4 > 20:
            self.AddEffect(GameEffect.LEVITATION, 5, 1, False)
            self.AddEffect(GameEffect.MOVEMENT_SPEED, 2, 1, False)
            self.SetGravity(0.00001)
        elif -30 <= p2 <= 15 or -30 <= p4 <= 15:
            self.DelEffect(GameEffect.LEVITATION)
            self.SetGravity(0.00001)
        else:
            self.DelEffect(GameEffect.LEVITATION)
            self.AddEffect(GameEffect.SLOW_FALLING, 4, 1, False)
            self.SetGravity(0.02)
        return True

    def StopFly(self):
        self.DelEffect(GameEffect.LEVITATION)
        self.SetGravity(0)
        playerId = self.GetTameOwner()
        if playerId:
            RawEntity.AddEffect(playerId, GameEffect.SLOW_FALLING, 4, 1, False)


class FrogManisEntity(CombineEntityBase):
    """雷鸣岩鳞兽"""

    def __init__(self, entityId):
        super(FrogManisEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(FrogManisEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "frog_manis_attack"
        })

        def active():
            if self._owner_player:
                yield 12
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(12):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                self.SetInstantDamage(entityId, self.attack)
                self.SetKnockEntityAtPos(entityId, 3, 2)
            yield 11
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(FrogManisEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "frog_manis_sk1_1"
            })
            if self._owner_player:
                yield 5
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(5):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            ban_set = {self.id, }
            self.SetJumpByKnock(1.5)
            self.AddEffect(GameEffect.SLOW_FALLING, 5, 1)
            yield 50
            self.SetForwardByKnock(6.0)
            yield 2
            self.SetJumpByKnock(-10.0)
            # self.SetMotion((self.GetDrt()[0] * 5, 0.0,self.GetDrt()[0] * 5))
            yield 8
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "frog_manis_sk1_2"
            })
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 7):
                if entityId not in ban_set:
                    ban_set.add(entityId)
                    self.SetInstantDamage(entityId, self.sk1_damage)
                    self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(FrogManisEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "frog_manis_sk2"
            })

            if self._owner_player:
                yield 6
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(6):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            self.AddEffect(GameEffect.MOVEMENT_SPEED, 3, 1)
            self.invincible = True
            yield 50
            self.invincible = False
            yield 10
            self.TriggerResetSkill()

        self.StartCoroutine(active)


class SlothManisEntity(CombineEntityBase):
    """睡爪岩鳞兽"""

    def __init__(self, entityId):
        super(SlothManisEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(SlothManisEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "sloth_manis_attack"
        })

        def active():
            if self._owner_player:
                yield 12
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(12):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                self.SetInstantDamage(entityId, self.attack)
                self.SetKnockEntityAtPos(entityId, 3, 2)
            yield 11
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(SlothManisEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "sloth_manis_sk1"
            })
            if self._owner_player:
                yield 5
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(5):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            ban_set = {self.id, self._owner_player}
            # self.SetJumpByKnock(1.5)
            entityList = []
            yield 7
            pos = self.GetPosForward(3)
            for entityId in self.GetMobAtPos(pos, 4):
                if entityId not in ban_set:
                    self.SetInstantDamage(entityId, self.sk1_damage)
                    entity = LivingEntity(entityId)
                    entity.SetJumpByKnock(1.5)
                    entity.SetGravity(0.02)
                    entityList.append(entity)
            yield 15
            pos = self.GetPosForward(3)
            for entityId in self.GetMobAtPos(pos, 4):
                if entityId not in ban_set:
                    self.SetInstantDamage(entityId, self.sk1_damage)
                    self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
            for entity in entityList:
                entity.SetGravity(0.0)
                entity.SetJumpByKnock(-10)
            yield 10
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(SlothManisEntity, self).ActiveSkill2()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "sloth_manis_sk2"
            })
            if self._owner_player:
                yield 5
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(5):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            ban_set = {self.id, }
            yield 16
            pos = self.GetPosForward(5)
            for entityId in self.GetMobAtPos(pos, 5):
                if entityId not in ban_set:
                    ban_set.add(entityId)
                    RawEntity.AddEffect(entityId, GameEffect.MOVEMENT_SLOWDOWN, 3, 4)
                    self.SetInstantDamage(entityId, self.sk2_damage)
                    self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
            yield 40
            self.TriggerResetSkill()

        self.StartCoroutine(active)


class ManisVelociraptorEntity(CombineEntityBase):
    """岩鳞迅猛兽"""

    def __init__(self, entityId):
        super(ManisVelociraptorEntity, self).__init__(entityId)
        self.sk1_time = False
        self.sk1_particle = None

    def ActiveAttack(self):
        super(ManisVelociraptorEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "manis_velociraptor_attack"
        })

        def active():
            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            for i in xrange(2):
                pos = self.GetPosForward(0)
                for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                    self.SetInstantDamage(entityId, self.attack)
                    self.SetKnockEntityAtPos(entityId, 3, 2)
                yield 12
            yield 10
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def OnDealDamage(self, args):
        entityId = args["entityId"]
        if args["damage"] == 1999:
            args["damage"] = 0
            args["knock"] = False
            if self.sk1_time:
                """打断"""
                if entityId in {self.id, self._owner_player}:
                    return
                self.sk1_stop()

    def sk1_stop(self):
        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "manis_velociraptor_sk1_2"
        })
        ban_set = {self.id, self._owner_player}
        self.sk1_particle.Destroy()
        self.DelEffect(GameEffect.MOVEMENT_SPEED)
        self.TriggerResetSkill()
        pos = self.GetPosForward(0)
        for entityId in self.GetMobAtPos(pos, 4):
            if entityId not in ban_set:
                self.SetInstantDamage(entityId, self.sk1_damage)
                LivingEntity(entityId).SetJumpByKnock(1.5)
                ban_set.add(entityId)
        self.sk1_time = False

    def ActiveSkill1(self):
        """但滚动有一个问题，就是如果不是玩家骑乘控制释放的时候，只是有个滚动状态，但不会动，并不会自己跑向敌人。
            所以如果优化的话我们可以判断是不是骑乘状态。然后如果不是的话，就自己用代码让他面向敌人，然后给突进
        """
        super(ManisVelociraptorEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "manis_velociraptor_sk1_1"
            })
            if self._owner_player:
                yield 6
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(6):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1

            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            self.AddEffect(GameEffect.MOVEMENT_SPEED, 5, 2)

            self.sk1_time = True
            self.sk1_particle = self.AddParticleEntity(GameEntity.detector, pos=self.GetPosForward(0, dy=0))
            self.sk1_particle.SetModel("base_entity")
            self.sk1_particle.SetFixBind("models/bind/v15_bind.json", "manis_velociraptor_sk1").Play()
            self.sk1_particle.SetTrackEntity(self.id, forward=0)
            if not self.GetRiders():
                """如果没有骑乘者，就自己跑向敌人"""
                targetId = self.GetAttackTarget()
                for i in xrange(30):
                    if not self.IsAlive() or not self.sk1_time:
                        return
                    self.SetFacingEntity(targetId)
                    self.SetForwardByKnock(2)
                    yield 5
            else:
                yield 5 * 30
            if not self.sk1_time:
                return
            self.sk1_particle.Destroy()
            self.sk1_time = False
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(ManisVelociraptorEntity, self).ActiveSkill2()

        # 右边的才是sk1
        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "manis_velociraptor_sk2"
            })
            if self._owner_player:
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(15):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            # self.PlayParticleBind("eagle_tiger_sk1")
            ban_set = {self.id, }
            pos = self.GetPosForward(5)
            self.sk1_particle = self.AddParticleEntity(GameEntity.detector, pos=pos)
            self.sk1_particle.SetModel("base_entity")
            self.sk1_particle.SetFixBind("models/bind/v15_bind.json", "manis_velociraptor_sk2").Play()
            for entityId in self.GetMobAtPos(pos, 6):
                if entityId not in ban_set:
                    ban_set.add(entityId)
                    self.SetInstantDamage(entityId, self.sk2_damage)
                    self.SetKnockEntityAtPos(entityId, 5, 4, height=0.8)
            yield 23
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def OnDestroy(self):
        super(ManisVelociraptorEntity, self).OnDestroy()
        self.sk1_particle.Destroy()


class SnakeChomperEntity(CombineEntityBase):
    """毒牙啃灵兽"""

    def __init__(self, entityId):
        super(SnakeChomperEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(SnakeChomperEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "snake_chomper_attack"
        })

        def active():
            if self._owner_player:
                yield 8
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(8):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            yield 14
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                self.SetInstantDamage(entityId, self.attack)
                self.SetKnockEntityAtPos(entityId, 2, 1)
                RawEntity.AddEffect(entityId, GameEffect.POISON, 3, 1)

            yield 5
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(SnakeChomperEntity, self).ActiveSkill1()

        # 右边的才是sk1
        def GunHit(projectile):
            hitType = projectile.hitType
            hitPos = projectile.GetHitPos()
            for entityId in self.GetMobAtPos(hitPos, 6, banList=[self.id, projectile.id, self._owner_player],
                                             filters=GameFilter.Mob):
                self.SetInstantDamage(entityId, 25)
                self.SetKnockEntityAtPos(entityId, 7, 5, height=1)
                self.SetEntityFire(entityId, 5)

        def active():
            """枪普攻"""
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "snake_chomper_sk1"
            })
            if self._owner_player:
                dir = self.drt
                yield 17
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                dir = self.GetFacingVec(RawEntity.GetPos(targetId))
                for i in xrange(17):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            sk1_particle = self.AddParticleEntity(GameEntity.detector, pos=self.GetPosForward(1, dy=3))
            sk1_particle.SetModel("base_entity")
            sk1_particle.SetFixBind("models/bind/v15_bind.json", "snake_chomper_sk1").Destroy(2).Play()
            sk1_particle.SetTrackEntity(self.id, forward=0)
            for i in range(10):
                pos = self.GetPosForward(4)
                for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                    self.SetInstantDamage(entityId, 5)
                    self.SetKnockEntityAtPos(entityId, 2, 1)
                yield 6
            yield 6
            pos = self.GetPosForward(1.5, dy=5.2, dx=0)

            projectile = ProjectileEntity.CreateFromEntity(GameEntity.projectile, self.id,
                                                           position=pos,
                                                           direction=dir,
                                                           power=2.0,
                                                           gravity=0.1)
            projectile.ConfigHitRecall(GunHit)
            projectile = projectile.asParticleEntity()
            projectile.SetModel("base_entity").Destroy(5.0).SetFixBind("models/bind/v15_bind.json",
                                                                       "snake_chomper_sk1_psw").Play()
            yield 15
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(SnakeChomperEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "snake_chomper_sk2"
            })

            if self._owner_player:
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(15):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1

            if not self.IsAlive():
                return
            ban_set = {self.id, self._owner_player}
            for i in range(5):
                pos = self.GetPosForward(0)
                self.SetForwardByKnock(3.0)
                for entityId in self.GetMobAtPos(pos, 3):
                    if entityId not in ban_set:
                        self.SetInstantDamage(entityId, self.sk2_damage)
                        LivingEntity(entityId).SetJumpByKnock(1.8)
                        ban_set.add(entityId)
                yield 1
            yield 15
            self.TriggerResetSkill()

        self.StartCoroutine(active)


class InkfishMantisEntity(CombineEntityBase):
    """墨脚巨斧兽"""

    def __init__(self, entityId):
        super(InkfishMantisEntity, self).__init__(entityId)

    def ActiveAttack(self):
        super(InkfishMantisEntity, self).ActiveAttack()

        self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
            "entityId": self.id,
            "path": "inkfish_mantis_attack1"
        })

        def active():
            if self._owner_player:
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(15):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    if i >= 5:
                        self.SetForwardByKnock(0.2)
                    yield 1
            for i in range(2):
                pos = self.GetPosForward(0)
                for entityId in self.GetMobAtPos(pos, 5, banList=[self.id]):
                    self.SetInstantDamage(entityId, self.attack)
                    self.SetKnockEntityAtPos(entityId, 2, 1)
                yield 16

            yield 13
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill1(self):
        super(InkfishMantisEntity, self).ActiveSkill1()

        def active():
            """枪普攻"""
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "inkfish_mantis_sk1"
            })
            if self._owner_player:
                dir = self.drt
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(15):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1
            if not self.IsAlive():
                return
            self.invincible = True
            yield 35
            self.invincible = False
            yield 5

            sk1_particle = self.AddParticleEntity(GameEntity.detector, pos=self.GetPosForward(1))
            sk1_particle.SetModel("base_entity")
            sk1_particle.SetFixBind("models/bind/v15_bind.json", "eagle_tiger_sk1").Destroy(1).Play()
            pos = self.GetPosForward(0)
            for entityId in self.GetMobAtPos(pos, 6, banList=[self.id]):
                self.SetInstantDamage(entityId, self.sk1_damage)
                self.SetKnockEntityAtPos(entityId, 2, 1)

            yield 15
            self.TriggerResetSkill()

        self.StartCoroutine(active)

    def ActiveSkill2(self):
        super(InkfishMantisEntity, self).ActiveSkill2()

        def active():
            self.BroadcastToAllClient(ServerEvent.ServerRequestPlayMusic, {
                "entityId": self.id,
                "path": "inkfish_mantis_sk2"
            })

            if self._owner_player:
                yield 15
                if not self.IsAlive():
                    return
            else:
                targetId = self.GetAttackTarget()
                for i in xrange(15):
                    if not self.IsAlive():
                        return
                    self.SetFacingEntity(targetId)
                    yield 1

            if not self.IsAlive():
                return
            ban_set = {self.id, self._owner_player}
            pos = self.GetPosForward(4)
            # self.SetForwardByKnock(3.0)
            for entityId in self.GetMobAtPos(pos, 4):
                if entityId not in ban_set:
                    self.SetInstantDamage(entityId, self.sk2_damage)
                    self.SetKnockEntityAtPos(entityId, 4, 3)
                    self.SetEntityFire(entityId, 3)
            yield 15
            self.TriggerResetSkill()

        self.StartCoroutine(active)
